<script setup>
import { ref } from "vue";
import { nanoid } from "nanoid";

const tableData = ref([
  {
    name: "",
    prop: "",
    id: nanoid(),
    search: "false",
    custom: false,
    options: [{ label: "", value: null }],
  },
]);

const removeField = (row) => {
  tableData.value = tableData.value.filter((item) => item.id !== row.id);
};

const color=ref('red')

const code = ref("");
const confirm = () => {
  let arrString = ""; //  生成el-table-column
  let searchString = ""; //  生成el-form-item
  let searchFormString = ""; //  生成searchForm.jsonParam
  let optionString = "" //生成选项

  tableData.value.forEach((e) => {
    if (e.custom) {
      arrString = arrString + 
        "  <el-table-column prop='" + e.prop + "' label='" + e.name + "'>\n" +
        "    <template #default='{row}'>\n" +
        "      {{row." + e.prop + "}}\n" +
        "    </template>\n" +
        "  </el-table-column>\n";
    } else {
      arrString =
        arrString +
        "  <el-table-column prop='" +
        e.prop +
        "' label='" +
        e.name +
        "' />\n";
    }
    if (e.search === "input") {
      searchFormString = searchFormString + `    ${e.prop}:"",` + "\n";
      searchString =
        searchString +
        "  <el-form-item prop='" + e.prop + "' label='" + e.name + "' >\n" +
        "    <el-input v-model='searchForm.jsonParam." + e.prop + "' />\n" +
        "  </el-form-item>\n";
    } else if (e.search === "select") {
      searchFormString = searchFormString + `    ${e.prop}:"",` + "\n";
      searchString = searchString +
        "  <el-form-item prop='" + e.prop + "' label='" + e.name + "' >\n" +
        "    <el-select class='w-40' v-model='searchForm.jsonParam." + e.prop + "'>\n" +
        "      <el-option v-for='(key,val) in "+ e.prop + "Options' :label='val' :value='key'></el-option>\n" +
        "    </el-select>\n" + 
        "  </el-form-item>\n";
      optionString += "const " + e.prop +"Options = {\n"
      e.options.forEach(e=>{
        optionString += `${e.value}: ${e.label},\n`
      })
      optionString = optionString + "}\n"
    }
  });

  let templateSearch = "";
  if (searchFormString) {
    templateSearch =
      "<el-form :inline='true' :model='searchForm.jsonParam' ref='formRef'>\n" +
      searchString +
      "  <el-form-item>\n" +
      "    <el-button type='primary' @click='search'>查询</el-button>\n" +
      "    <el-button @click='resetSearch'>重置</el-button>\n" +
      "  </el-form-item>\n" +
      "</el-form>\n";
  }

  const codeParts = [
    "<template>",
    templateSearch,
    "<el-table :data='tableData.data' @selection-change='handleSelectionChange'>",
    "  <el-table-column type='selection' width='40' />",
    arrString,
    "  <el-table-column label='操作'>",
    "    <template #default='{ row }'>",
    "      <el-button link type='primary' size='small' @click='edit(row)'>编辑</el-button>",
    "      <el-button link type='danger' size='small' @click='remove([row.id])'>删除</el-button>",
    "    </template>",
    "  </el-table-column>",
    "</el-table>",
    "<div>",
    "  <el-pagination",
    "    v-if='tableData.totalCount > 0'",
    "    background",
    "    v-model:current-page='searchForm.pageNo'",
    "    v-model:page-size='searchForm.pageSize' :page-sizes='[10, 20, 30]'",
    "    layout='prev, pager, next, jumper, sizes' :total='tableData.totalCount'",
    "    @size-change='search'",
    "    @current-change='setTableData'",
    "  />",
    "</div>",
    "</template>",
    "<script setup>",
    "import { reactive, ref } from 'vue';",
    "import {ElMessage, ElMessageBox} from 'element-plus';\n",
    "const loading = ref(false);",
    "const searchForm = reactive({",
    "  pageNo: 1,",
    "  pageSize: 10,",
    "  jsonParam: {",
    searchFormString,
    "  }",
    "});\n",
    "const tableData = ref({",
    "  data: [],",
    "  pageNo: 0,",
    "  pageSize: 0,",
    "  totalCount: 0,",
    "});\n",
    "const setTableData = () => {};",
    "const search = () => {",
    "  searchForm.pageNo = 1;",
    "  setTableData();",
    "};\n",
    "const selection = ref([]);",
    "const handleSelectionChange = (val) => {",
    "  selection.value = val;",
    "};\n",
    "const remove = async ids => {",
    "  try {",
    "    await ElMessageBox.confirm('确定删除吗?', '删除提示', { type: 'warning' });",
    "    loading.value = true;",
    "    const ids = ids ?? selection.value.map(el => el.id);",
    "    search();",
    "  } catch (err) {",
    "    if (err !== 'cancel') {",
    "      ElMessage.error(err)",
    "    }",
    "  } finally {",
    "    loading.value = false;",
    "  }",
    "};\n",
    "const formVisible = ref(false);",
    "const edit = (data) => {};\n",
    "const formRef = ref();",
    "const resetSearch = () => {",
    "  formRef.value.resetFields();",
    "  search();",
    "};\n",
    optionString,
    "</" + "script>",
  ];

  code.value = codeParts.join("\n");
};
</script>

<template>
  <h1 class="test-color">自动生成带查询表格的el-table</h1>

  <div class="box">
    <el-table :data="tableData" border>
      <el-table-column prop="name" label="name">
        <template #default="{ row }">
          <el-input v-model="row.name" />
        </template>
      </el-table-column>
      <el-table-column prop="prop" label="prop">
        <template #default="{ row }">
          <el-input v-model="row.prop"></el-input>
        </template>
      </el-table-column>
      <el-table-column prop="search" label="查询" width="100px">
        <template #default="{ row }">
          <el-select v-model="row.search">
            <el-option :value="'false'" label="无"></el-option>
            <el-option :value="'select'" label="选择"></el-option>
            <el-option :value="'input'" label="输入"></el-option>
          </el-select>
        </template>
      </el-table-column>
      <el-table-column prop="options" label="选项" width="300px">
        <template #default="{ row }">
          <div v-if="row?.search == 'select'">
            <div v-for="(i, index) in row.options" :key="index" class="flex">
              <el-input
                v-model="row.options[index].label"
                placeholder="label"
              ></el-input>
              <el-input
                v-model="row.options[index].value"
                placeholder="value"
              ></el-input>
              <el-button link @click="row.options.splice(index, 1)"
                >删除</el-button
              >
            </div>
            <el-button @click="row.options.push({ label: '', value: null })"
              >添加</el-button
            >
          </div>
          <div v-else></div>
        </template>
      </el-table-column>
      <el-table-column prop="custom" label="自定义内容" width="100px">
        <template #default="{ row }">
          <el-switch v-model="row.custom"></el-switch>
        </template>
      </el-table-column>
      <el-table-column width="100px">
        <template #default="{ row }">
          <el-button link @click="removeField(row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <div class="foot">
      <el-button
        @click="
          tableData.push({
            name: '',
            prop: '',
            id: nanoid(),
            search: 'false',
            custom: false,
            options: [{ label: '', value: null }],
          })
        "
      >
        添加
      </el-button>
      <el-button @click="confirm" type="primary">确认</el-button>
    </div>

    <highlightjs
      language="JavaScript"
      :autodetect="false"
      :code="code"
      v-show="code"
    ></highlightjs>
  </div>
</template>

<style scoped>
.el-input {
  width: 200px;
}

.box {
  margin: 0 auto;
}

.foot {
  text-align: center;
  margin-top: 20px;
}

h1 {
  text-align: center;
}

.flex {
  display: flex;
  gap: 5px;
}

.test-color{
  color:v-bind(color);
  margin-bottom: 20px;
}
</style>
